#pragma once
#include <windows.h>
#include <GL/gl.h>

//+==================================================================+
class Window3D
{
public:
//////////////////////////////////////////////////////////////////////
	Window3D(int w = 640, int h = 480, LPCTSTR caption = NULL, bool fullscreen = false);
	~Window3D();

	bool initialize();
	void show(bool show = true);
	void resize(int width, int height);
	void switchFullscreen(bool fullscreen = true);

	HWND							getHWND()			{	return hWnd;			}
	HDC							getDC()				{	return hDC;				}
	HGLRC							getRC()				{	return hRC;				}

//+------------------------------------------------------------------+
//	Creates a window by a new message handling thread.
//	The window is owned by the thread, and will exist for its lifetime.
	static Window3D *CreateWindowAndThread();

//+------------------------------------------------------------------+
//	Windows created with "CreateWindowAndThread" will wait for all
//	reference holders to release their handles and then be deleted.
	void	quit()										{ quitThread = true;		}
	bool	isQuitting()								{ return quitThread;		}
	void	addReference();
	void	removeReference();

//+------------------------------------------------------------------+
//	Callbacks for window events, like mouse and keyboard input.
	bool(*handleMouseEvent)	(MSG &msg);
	bool(*handleKeyEvent)	(MSG &msg);
	void(*render)();

//+------------------------------------------------------------------+
//	returns size of the client area.
//	int	getWidth()  const							{ return clientW;			}
//	int	getHeight() const							{ return clientH;			}

private:
//////////////////////////////////////////////////////////////////////
	static LRESULT CALLBACK WndProc(HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam);
	static DWORD WINAPI WindowThread(LPVOID lpParam);

//+------------------------------------------------------------------+
	HWND							hWnd;			// Window Handle
	HDC							hDC;			// GDI Device Context
	HGLRC							hRC;			// OpenGL Rendering Context
//----
//	int							clientW,		//	width  of client window; updated in message loop
//									clientH;		//	height of client window; updated in message loop
//----
	DWORD							threadID;
	HANDLE						threadHandle;
	bool							quitThread;	// If set to true, the message thread will try to return.
	bool							fullscreen;	// To toggle between windowed and fullscreen
	int							references;	// number of references depending on that window
	CRITICAL_SECTION			refAccess;
};


